/*
 * File:        hal_frame.c
 * Author:      buquan_chen
 * Comments:    the new framework
 * Data:        2024/12/13
 * Revision history: V0.1
 */
#include <hal_frame.h>
#include "string.h"
// CRC lookup table for quick computation of CRC values
static const unsigned char crc_table[] = {
    0x00,0x31,0x62,0x53,0xc4,0xf5,0xa6,0x97,0xb9,0x88,0xdb,0xea,0x7d,0x4c,0x1f,0x2e,
    0x43,0x72,0x21,0x10,0x87,0xb6,0xe5,0xd4,0xfa,0xcb,0x98,0xa9,0x3e,0x0f,0x5c,0x6d,
    0x86,0xb7,0xe4,0xd5,0x42,0x73,0x20,0x11,0x3f,0x0e,0x5d,0x6c,0xfb,0xca,0x99,0xa8,
    0xc5,0xf4,0xa7,0x96,0x01,0x30,0x63,0x52,0x7c,0x4d,0x1e,0x2f,0xb8,0x89,0xda,0xeb,
    0x3d,0x0c,0x5f,0x6e,0xf9,0xc8,0x9b,0xaa,0x84,0xb5,0xe6,0xd7,0x40,0x71,0x22,0x13,
    0x7e,0x4f,0x1c,0x2d,0xba,0x8b,0xd8,0xe9,0xc7,0xf6,0xa5,0x94,0x03,0x32,0x61,0x50,
    0xbb,0x8a,0xd9,0xe8,0x7f,0x4e,0x1d,0x2c,0x02,0x33,0x60,0x51,0xc6,0xf7,0xa4,0x95,
    0xf8,0xc9,0x9a,0xab,0x3c,0x0d,0x5e,0x6f,0x41,0x70,0x23,0x12,0x85,0xb4,0xe7,0xd6,
    0x7a,0x4b,0x18,0x29,0xbe,0x8f,0xdc,0xed,0xc3,0xf2,0xa1,0x90,0x07,0x36,0x65,0x54,
    0x39,0x08,0x5b,0x6a,0xfd,0xcc,0x9f,0xae,0x80,0xb1,0xe2,0xd3,0x44,0x75,0x26,0x17,
    0xfc,0xcd,0x9e,0xaf,0x38,0x09,0x5a,0x6b,0x45,0x74,0x27,0x16,0x81,0xb0,0xe3,0xd2,
    0xbf,0x8e,0xdd,0xec,0x7b,0x4a,0x19,0x28,0x06,0x37,0x64,0x55,0xc2,0xf3,0xa0,0x91,
    0x47,0x76,0x25,0x14,0x83,0xb2,0xe1,0xd0,0xfe,0xcf,0x9c,0xad,0x3a,0x0b,0x58,0x69,
    0x04,0x35,0x66,0x57,0xc0,0xf1,0xa2,0x93,0xbd,0x8c,0xdf,0xee,0x79,0x48,0x1b,0x2a,
    0xc1,0xf0,0xa3,0x92,0x05,0x34,0x67,0x56,0x78,0x49,0x1a,0x2b,0xbc,0x8d,0xde,0xef,
    0x82,0xb3,0xe0,0xd1,0x46,0x77,0x24,0x15,0x3b,0x0a,0x59,0x68,0xff,0xce,0x9d,0xac
};

struct custom_action_type action = {0};

void write_action(uint8_t action,uint8_t *buf,uint16_t len);

#if HAL_FRAME_ENVIRONMENT
char *config_readbuf = NULL;

/**
 * @brief Mode data initialization function.
 *
 * This function is used to initialize the mode data, reading the mode data from the configuration file and storing it in the config_readbuf array.
 *
 * @return None
 */
void mode_data_init()
{
	config_readbuf = (char *)(malloc(CUSTOM_MODE_SIZE*CUSTOM_MODE_NUM));
	memset(config_readbuf, 0, sizeof(config_readbuf));
	
    if(config_readbuf != NULL)
    {
        printf("ss=%d\r\n",syscfg_read(mode1,config_readbuf,CUSTOM_MODE_SIZE));
        printf("ss=%d\r\n",syscfg_read(mode2,config_readbuf+CUSTOM_MODE_SIZE,CUSTOM_MODE_SIZE));
        printf("ss=%d\r\n",syscfg_read(mode3,config_readbuf+CUSTOM_MODE_SIZE*2,CUSTOM_MODE_SIZE));
		// printf("ss=%d\r\n",syscfg_read(mode4,config_readbuf+CUSTOM_MODE_SIZE*3,CUSTOM_MODE_SIZE));
		// printf("ss=%d\r\n",syscfg_read(mode5,config_readbuf+CUSTOM_MODE_SIZE*4,CUSTOM_MODE_SIZE));
		// printf("ss=%d\r\n",syscfg_read(mode6,config_readbuf+CUSTOM_MODE_SIZE*5,CUSTOM_MODE_SIZE));
    }
}

/**
 * @brief Retrieves a frame from the configuration buffer based on the action and offset.
 *
 * This function reads three bytes from a specific location within the
 * `config_readbuf` array, determined by the `action` parameter and
 * `address_offset`. The retrieved bytes are stored in the `buf` parameter.
 * 
 * The function checks if the first byte of the retrieved data contains certain
 * flags and returns a value indicating the frame type.
 *
 * @param action The action identifier used to determine the starting location
 *               in the `config_readbuf`.
 * @param address_offset The offset added to the base address for the specific
 *                       action to locate the desired frame.
 * @param buf A pointer to a `union frame_type` where the retrieved frame data
 *            will be stored.
 * @return A uint8_t indicating the type of frame:
 *         - END_FRAME_TYPE if the frame is an end frame.
 *         - A masked level value if it is a looping frame.
 *         - ACTION_FRAME_TYPE if it is a standard action frame.
 *         Returns 0 if the buffer is uninitialized or if the address is invalid.
 */
static uint8_t get_frame(uint8_t action,uint32_t address_offset,union frame_type *buf)
{
	uint8_t i;
	uint8_t *address = NULL;
	
	if(config_readbuf == NULL)
	{
		printf("buf err\r\n");
		return 0;
	}
	switch(action)
	{
		case 1:
			address = config_readbuf + 0 + address_offset;break;
		case 2:
			address = config_readbuf + CUSTOM_MODE_SIZE*(action-1) + address_offset;break;
		case 3:
			address = config_readbuf + CUSTOM_MODE_SIZE*(action-1) + address_offset;break;
		case 4:
			address = config_readbuf + CUSTOM_MODE_SIZE*(action-1) + address_offset;break;
		case 5:
			address = config_readbuf + CUSTOM_MODE_SIZE*(action-1) + address_offset;break;
		case 6:
			address = config_readbuf + CUSTOM_MODE_SIZE*(action-1) + address_offset;break;
		default:
			return 0;
	}
	
	buf->_data[0] = address[0];
	buf->_data[1] = address[1];	
	buf->_data[2] = address[2];

    // printf("read :");
    // for (i = 0; i < 3; i++)
    // {
    //     printf("%02X ",buf->_data[i]);
    // }
    // printf("\r\n");	
		
	if(address[0] & END_MASK)
	{
		return END_FRAME_TYPE;
	}
	if(address[0] & LEVEL_MASK)
	{
		return address[0] &  LEVEL_MASK;  //循环帧
	}
	return ACTION_FRAME_TYPE;
}

/**
 * @brief Writes data to flash memory in 1KB chunks.
 *
 * @param address The starting address of the flash memory block to write to.
 * @param buf The data to be written to flash memory.
 * @param len The length of the data to be written in bytes.
 *
 * @note This function writes the data in 1KB chunks by calling syscfg_write() with
 *       a length of 1024 bytes. If the length of the data is not a multiple of 1024,
 *       the remaining bytes will be padded with zeros.
 */
static void flash_write_1k(uint32_t address,uint8_t *buf,uint16_t len)
{
	// syscfg_write(address,buf,1024);
	syscfg_write(address,buf,len);
}

/**
 * @brief Writes data to flash memory with left alignment and padding.
 *
 * This function reads the existing data from the specified flash memory
 * address into a buffer, then copies the provided data into the buffer,
 * left-aligning it. It pads the remaining space in the buffer with zeros
 * to ensure alignment. Finally, it writes the entire buffer back to the
 * flash memory.
 *
 * @param address The starting address of the flash memory block to write to.
 * @param buf A pointer to the data to be written to flash memory.
 * @param len The length of the data to be written in bytes.
 *
 * @note The function reads 1024 bytes from the flash memory, allowing for
 *       a buffer size that is twice the alignment value to accommodate
 *       the new data and padding.
 */
static void flash_write_left(uint32_t address,uint8_t *buf,uint16_t len)
{
	uint16_t offset = 0;
	uint16_t left = len;
	uint16_t aligned_len = 512; // Round up to the nearest multiple of 512
    uint8_t padded_buf[aligned_len*2];
	syscfg_read(address,padded_buf,1024);
    
	memcpy(padded_buf,buf,len);

	memset(padded_buf+len,0,aligned_len-len);	// Padding with zeros

	syscfg_write(address,padded_buf,1024);
}

/**
 * @brief Writes data to flash memory with right alignment and padding.
 *
 * This function reads the existing data from the specified flash memory
 * address into a buffer, then copies the provided data into the buffer,
 * right-aligning it. It pads the remaining space in the buffer with zeros
 * to ensure alignment. Finally, it writes the entire buffer back to the
 * flash memory.
 *
 * @param address The starting address of the flash memory block to write to.
 * @param buf A pointer to the data to be written to flash memory.
 * @param len The length of the data to be written in bytes.
 *
 * @note The function reads 1024 bytes from the flash memory, allowing for
 *       a buffer size that is twice the alignment value to accommodate
 *       the new data and padding.
 */
static void flash_write_right(uint32_t address,uint8_t *buf,uint16_t len)
{
	uint16_t offset = 0;
	uint16_t left = len;
	uint16_t aligned_len = 512; // Round up to the nearest multiple of 512
    uint8_t padded_buf[aligned_len*2];
	syscfg_read(address,padded_buf,1024);
    
	memcpy(padded_buf+512,buf,len);

	memset(padded_buf+512+len,0,aligned_len-len);	// Padding with zeros

	syscfg_write(address,padded_buf,1024);
}
#ifdef CONFIG_BOARD_7916AB	//use AC79
void write_action(uint8_t action,uint8_t *buf,uint16_t len)
{
	switch(action)
	{
		case 1:
			flash_write_1k(mode1,buf,len);
			printf("xxxx \r\n");
			printf("ss=%d\r\n",syscfg_read(mode1,config_readbuf,CUSTOM_MODE_SIZE));
			break;
		case 2:
			flash_write_1k(mode2,buf,len);
			printf("xxxx \r\n");
			printf("ss=%d\r\n",syscfg_read(mode2,config_readbuf+CUSTOM_MODE_SIZE,CUSTOM_MODE_SIZE));
			break;
		case 3:
			flash_write_1k(mode3,buf,len);
			printf("xxxx \r\n");
			printf("ss=%d\r\n",syscfg_read(mode2,config_readbuf+CUSTOM_MODE_SIZE*2,CUSTOM_MODE_SIZE));
			break;			
		case 4:
		    flash_write_1k(mode4,buf,len);
			printf("xxxx \r\n");
			break;
		case 5:
		    flash_write_1k(mode5,buf,len);
			printf("xxxx \r\n");
			break;
		case 6:
		    flash_write_1k(mode6,buf,len);
			printf("xxxx \r\n");
			break;			
		default:
			break;		
		
	}
}
#else	//use AC69
void write_action(uint8_t action,uint8_t *buf,uint16_t len)
{
	switch(action)
	{
		case 1:
			flash_write_left(mode1,buf,len);
			printf("xxxx \r\n");
			break;
		case 2:
			flash_write_right(mode2,buf,len);
			printf("xxxx \r\n");
			break;
		case 3:
			flash_write_left(mode3,buf,len);
			printf("xxxx \r\n");
			break;			
		case 4:
		    flash_write_right(mode4,buf,len);
			printf("xxxx \r\n");
			break;
		case 5:
		    flash_write_left(mode5,buf,len);
			printf("xxxx \r\n");
			break;
		case 6:
		    flash_write_right(mode6,buf,len);
			printf("xxxx \r\n");
			break;			
		default:
			break;		
		
	}
}

#endif
#else
/**
 * @brief Writes data to flash memory.
 *
 * This function writes a specified length of data from a buffer to a given
 * flash memory address.
 *
 * @param address The starting address in flash memory where data will be written.
 * @param buf A pointer to the buffer containing the data to be written.
 * @param len The number of bytes to write from the buffer to flash memory.
 */
static void flash_write(uint32_t address,uint8_t *buf,uint16_t len)
{
	//Implementing writting data
}

/**
 * @brief Reads data from flash memory.
 *
 * This function reads a specified length of data from a given flash memory
 * address into a buffer.
 *
 * @param address The starting address in flash memory where data will be read.
 * @param buf A pointer to the buffer that will store the data read from flash
 *            memory.
 * @param len The number of bytes to read from flash memory into the buffer.
 */
static void flash_read(uint32_t address,uint8_t *buf,uint16_t len)
{
	//Implementing reading data
}

/**
 * @brief Retrieves a frame from flash memory based on action and offset.
 *
 * This function calculates the address in flash memory using the provided 
 * action and address_offset, reads three bytes from that location, and stores 
 * the data in the provided buffer. It then determines the type of frame based 
 * on the flags in the first byte of the retrieved data.
 *
 * @param action The action identifier used to determine the base address.
 * @param address_offset The offset added to the base address for the action.
 * @param buf A pointer to a `union frame_type` where the retrieved frame data 
 *            will be stored.
 * 
 * @return A uint8_t indicating the type of frame:
 *         - END_FRAME_TYPE if the frame is an end frame.
 *         - A masked level value if it is a looping frame.
 *         - ACTION_FRAME_TYPE if it is a standard action frame.
 *         Returns 0 if the address is invalid.
 */
static uint8_t get_frame(uint8_t action,uint32_t address_offset,union frame_type *buf)
{
	uint32_t address = 0;
	uint8_t tmp_data[4];
	switch(action)
	{
		case 1:
			address = custom_mode1_adress + address_offset;break;
		case 2:
			address = custom_mode2_adress + address_offset;break;
		case 3:
			address = custom_mode3_adress + address_offset;break;
		case 4:
			address = custom_mode4_adress + address_offset;break;
		case 5:
		    address = custom_mode5_adress + address_offset;break;
		case 6:
			address = custom_mode6_adress + address_offset;break;
		default:
			return 0;
	}

	flash_read(address,&tmp_data[0],3);
	buf->_data[0] = tmp_data[0];
	buf->_data[1] = tmp_data[1];	
	buf->_data[2] = tmp_data[2];
		
	if(tmp_data[0] & END_MASK)
	{
		return END_FRAME_TYPE;
	}
	if(tmp_data[0] & LEVEL_MASK)
	{
		return tmp_data[0] &  LEVEL_MASK;  //ѭ��֡
	}
	return ACTION_FRAME_TYPE;
}

/**
 * @brief Writes a sequence of bytes to flash memory based on action.
 *
 * This function uses the provided action identifier to determine the base
 * address for the write operation. It then calls the underlying flash write
 * function to write the data to flash memory.
 *
 * @param action The action identifier used to determine the base address.
 * @param buf A pointer to a buffer containing the data to be written.
 * @param len The length of the data in the buffer.
 */
void   write_action(uint8_t action, uint8_t *buf, uint16_t len)
{
	switch (action)
	{
	case 1:
		flash_write(custom_mode1_adress, buf, len);
		printf("xxxx \r\n");
		break;
	case 2:
		flash_write(custom_mode2_adress, buf, len);
		printf("xxxx \r\n");
		break;
	case 3:
		flash_write(custom_mode3_adress, buf, len);
		printf("xxxx \r\n");
		break;
	case 4:
		flash_write(custom_mode4_adress, buf, len);
		printf("xxxx \r\n");
		break;
	case 5:
		flash_write(custom_mode5_adress, buf, len);
		printf("xxxx \r\n");
		break;
	case 6:
		flash_write(custom_mode6_adress, buf, len);
		printf("xxxx \r\n");
		break;
	default:
		break;
	}
}

#endif

/**
 * @brief Retrieves the current action based on the action ID and frame type.
 *
 * @details This function evaluates the current action by retrieving a frame from flash memory 
 *          using the current action ID and next address. It processes different frame types:
 *          - For action frames, it computes a motor setting value from the frame data.
 *          - For cycle frames, it manages loop iterations and updates the next address.
 *          - For end frames, it resets the action ID.
 *
 * @return A uint16_t value representing the current motor settings if successful, or 0 if the 
 *         action ID is zero or the frame is an end frame.
 *
 * @see set_action, custom_action_init, get_frame
 */
uint16_t get_ation(void)
{
	uint8_t type = 0;
	uint16_t ans = 0;
	if(action.action_id == 0) return 0;
	again:
	type = get_frame(action.action_id,action.nxt_address,&action.frame);
	if(type == 1)//动作帧
	{
		ans = (action.frame.action_frame.action_set_H << 8) + action.frame.action_frame.action_set_L;
		if(action.frame.action_frame.action_set_L & XXXX_TYPE)
		{
		}
		else
		{
		}
		if(++action.level0_times ==  action.frame.action_frame.time)
		{
			action.nxt_address += 3;
			action.level0_times = 0;
		}	
	}
	else//循环帧和结束帧
	{
		if(type == CYCLE01_FRAME_TYPE)  
		{
			if(++action.level1_times < action.frame.fun_frame.cycle_times)
			{
				action.nxt_address = action.frame.fun_frame.next_address | ((action.frame.fun_frame.level & 0x0F) << 8);
			}
			else
			{
				action.level1_times = 0;
				action.nxt_address += 3;
			}
			goto again;
		}
		else if(type == CYCLE02_FRAME_TYPE)  
		{
			if(++action.level2_times < action.frame.fun_frame.cycle_times)
			{
				action.nxt_address = action.frame.fun_frame.next_address | ((action.frame.fun_frame.level & 0x0F) << 8);
				//action.level2_times++;
			}
			else
			{
				action.level2_times = 0;
				action.nxt_address += 3;
			}
			goto again;
		}	
		else if(type == CYCLE03_FRAME_TYPE)  
		{
			if(++action.level3_times < action.frame.fun_frame.cycle_times)
			{
				action.nxt_address = action.frame.fun_frame.next_address | ((action.frame.fun_frame.level & 0x0F) << 8);
				//action.level3_times++;
			}
			else 
			{
				action.level3_times = 0;
				action.nxt_address += 3;
			}
			goto again;
		}	
    else if(type == END_FRAME_TYPE)  
		{
			action.action_id = 0;
		}
	}

	return ans;
	
}
/**
 * @brief   Initialize the custom action data structure
 *
 * @details This function initializes all fields of the custom action data structure to zero.
 *          It is called at the beginning of the program to reset the data structure.
 *
 * @see     get_ation, set_action, Hal_frame_analy_recv
 */
void custom_action_init(void)
{
	action.level0_times = 0;
	action.level1_times = 0;
	action.level2_times = 0;
	action.level3_times = 0;	
	
	action.action_id = 0;
	action.nxt_address = 0;
	
	action.frame._data[0] = 0;
	action.frame._data[1] = 0;
	action.frame._data[2] = 0;
}

/**
 * @brief   Set the action id to the custom action data structure
 *
 * @details This function sets the action id to the custom action data structure
 *          and resets all other fields of the data structure to zero.
 *
 * @param[in]   id         The action id to set
 *
 * @see     get_ation, custom_action_init
 */
void set_action(uint8_t id)
{
	action.level0_times = 0;
	action.level1_times = 0;
	action.level2_times = 0;
	action.level3_times = 0;	
	
	action.action_id = id;
    action.nxt_address = 0;
	
	action.frame._data[0] = 0;
	action.frame._data[1] = 0;
	action.frame._data[2] = 0;
	printf("action id = %u\r\n",action.action_id);
}
/**
 * @brief   Analyze a frame received from the phone and store the frame data
 *          to the corresponding custom mode
 *
 * @details This function analyzes a frame received from the phone and stores the
 *          frame data to the corresponding custom mode. The first byte of the
 *          frame data is used to determine the custom mode to write to.
 *
 * @param[in]  buf    Pointer to the frame data
 * @param[in]  len    Length of the frame data
 *
 * @see     write_action
 */
void Hal_frame_protocol_analy(uint8_t *buf,uint16_t len)
{
	if(buf[0] == 1)
	{		
		write_action(1,&buf[1],len - 2);	
	}
	else if(buf[0] == 2)
	{
		write_action(2,&buf[1],len - 2);
	}
	else if(buf[0] == 3)
	{
		write_action(3,&buf[1],len - 2);
	}
	else if(buf[0] == 4)	
	{
		write_action(4,&buf[1],len - 2);
	}
	else if(buf[0] == 5)
	{
		write_action(5,&buf[1],len - 2);
	}
	else if(buf[0] == 6)	
	{
		write_action(6,&buf[1],len - 2);
	}
}

/**
 * @brief      Calculate the CRC for the given buffer
 *
 * @param[in]  buf   Pointer to the data buffer
 * @param[in]  len   Length of the data buffer
 *
 * @return     The calculated CRC value
 *
 * @details    This function computes the CRC by iterating over each byte in the
 *             provided buffer and updating the CRC value using a predefined
 *             CRC table. The function returns the final CRC value.
 */
uint8_t Hal_frame_crc(uint8_t *buf,uint16_t len)
{
	uint8_t  crc = 0x00;
 
    while (len--)
    {
        crc = crc_table[crc ^ *buf];
			  buf++;
    }
	return crc;
}

uint8_t send_data(uint8_t *buf,uint16_t len)
{
	//Implementing sending data
	return 0;
}

/**
 * @brief      Send a packet to the phone
 *
 * @param[in]  commandType  Type of command to send
 * @param[in]  data         Data to send
 * @param[in]  dataLength   Length of the data to send
 *
 * @details    This function constructs a packet with the given command type and
 *             data, calculates the CRC, and sends the packet over the
 *             communication channel.
 */
void Hal_frame_send_data(uint8_t commandType, uint8_t *data, uint16_t dataLength)
{
    uint8_t packet[32] = {0};
    uint16_t index = 0;

    packet[index++] = 0x51;
    packet[index++] = 0x98;

    // key_index = (key_index + 1) % 4;
    // packet[index++] = key_index; // Key index placeholder

    packet[index++] = 0x00; // unused

    // Increase the sequence number and wrap around if it exceeds 255
    // last_sequence_number = (last_sequence_number + 1) % 256;
    // packet[index++] = last_sequence_number; // Sequence number

	packet[index++] = 0x00; // unused

    packet[index++] = 0x00; // Device type
    packet[index++] = 0x00; // Device ID
    packet[index++] = 0x02; // Direction (0x01: to device, 0x02: to phone)
    packet[index++] = 0x00; // CRC
    packet[index++] = commandType;
    packet[index++] = dataLength >> 8;
	packet[index++] = dataLength&0xFF;


    memcpy(&packet[index], data, dataLength);
    index += dataLength;

    // Calculate CRC
    uint8_t crc = Hal_frame_crc(&packet[8], dataLength); // Polynomial 0x31
    packet[7] = crc;

    printf("Sending packet: ");
    for (int i = 0; i < index; i++) {
        printf("%02X ", packet[i]);
    }
    printf("\r\n");
	
    send_data(packet, index);
}

/**
 * @brief      Analyze a frame received from the phone
 *
 * @param[in]  pValue  Pointer to the frame data
 * @param[in]  len     Length of the frame data
 *
 * @return     None
 *
 * @details    This function verifies the frame header, checks the CRC, and extracts
 *             the fields from the packet. It then processes the command based on
 *             the command type. If the command is unknown, it prints an error message.
 */
void Hal_frame_analy_recv(uint8_t *pValue, uint16_t len)
{
    uint8_t datatemp[32] = {0};
    if (len < 11) return; // Minimum length to include header, length, command, data, CRC

    // Check packet header
    if (pValue[0] != 0x51 || pValue[1] != 0x98) return;

    uint8_t crc = pValue[7];
    // Calculate CRC over data from index 9 to the end
    uint8_t calculatedCrc = Hal_frame_crc(&pValue[8], len - 8); // Polynomial 0x31

    if (crc != calculatedCrc) 
	{
		printf("CRC mismatch\r\n");
		// datatemp[0] = errorcode;
		// Hal_frame_send_data(0xfe,datatemp,1);	//send error msg
		return; // CRC mismatch
	}

    // Extract fields from the packet
//    uint8_t keyIndex = pValue[2];
//    uint8_t sequence = pValue[3];
//    uint8_t deviceType = pValue[4];
//    uint8_t deviceId = pValue[5];
//    uint8_t direction = pValue[6];
    uint8_t commandType = pValue[8];
    uint16_t dataLength = pValue[9]<<8 | pValue[10];
    uint8_t *data = &pValue[11];

	if (len != 11 + dataLength)
	{
		printf("Data length mismatch\r\n");
		// datatemp[0] = errorcode;
		// Hal_frame_send_data(0xfe,datatemp,1);	//send error msg
		return;
	}

    // Update the last received sequence number
    // last_sequence_number = sequence;
    // keyIndex = key_index;

    // Process command
    switch (commandType) {
        case 0x00:
            // Handle command 0x00
			Hal_frame_protocol_analy(data,len);

            datatemp[0] = 1;
            Hal_frame_send_data(0xff,datatemp,1);
            printf("Command 0x00 received with data length %d\r\n", dataLength);
            break;
        default:
            // Unknown command
            printf("Unknown command 0x%02X received\r\n", commandType);
            break;
    }
}
